import CognitoCallout from './cognito-callout.mdx';
import CLI from './quick-start-pull-cli.mdx';
import Callout from './credentials-provider-callout.mdx';
import { Alert, Tabs } from '@aws-amplify/ui-react';
import AppDirectoryAlert from '@/components/AppDirectoryAlert';
import { InstallScripts, TerminalCommand } from '@/components/InstallScripts';
import Liveness from './liveness-service-setup.mdx';

There are multiple methods to setup the Amazon Cognito resources needed for Amplify Auth. The recommended option is using Amplify Gen 2 to generate an Auth backend.

<CognitoCallout />

<Tabs.Container defaultValue="Gen 2">
  <Tabs.List>
    <Tabs.Item value="Gen 2">Amplify Gen 2</Tabs.Item>
    <Tabs.Item value="Amplify CLI">Amplify Gen 1</Tabs.Item>
    <Tabs.Item value="Amplify CLI Import">Amplify Gen 1 Import</Tabs.Item>
    <Tabs.Item value="Custom Credentials Provider">Custom Credentials Provider</Tabs.Item>
  </Tabs.List>
  <Tabs.Panel value="Gen 2">
> Use Amplify Gen 2 to setup and manage your Cognito Identity and User Pool in code

FaceLivenessDetector uses Amplify Auth by default to authorize users to perform the Face Liveness check. If you are using Amplify for the first time, follow the instructions for [installing Amplify Gen 2](https://docs.amplify.aws/react/start/).

<Tabs.Container defaultValue="npm">
  <Tabs.List>
    <Tabs.Item value="npm">npm</Tabs.Item>
    <Tabs.Item value="yarn">yarn</Tabs.Item>
  </Tabs.List>
  <Tabs.Panel value="npm">
    <TerminalCommand command="npm add --save-dev @aws-amplify/backend@latest @aws-amplify/backend-cli@latest" />
  </Tabs.Panel>
  <Tabs.Panel value="yarn">
    <TerminalCommand command="yarn add @aws-amplify/backend@latest @aws-amplify/backend-cli@latest --dev" />
  </Tabs.Panel>
</Tabs.Container>

Then follow the instructions for setting up a default [Amplify Auth resource](https://docs.amplify.aws/react/build-a-backend/auth/set-up-auth/).

Now that you have Amplify Auth setup, add the following code to your `backend.ts` file to create an inline policy to enable authenticated app users to access Rekognition.

```jsx
const livenessStack = backend.createStack("liveness-stack");

const livenessPolicy = new Policy(livenessStack, "LivenessPolicy", {
  statements: [
    new PolicyStatement({
      actions: ["rekognition:StartFaceLivenessSession"],
      resources: ["*"],
    }),
  ],
});
backend.auth.resources.unauthenticatedUserIamRole.attachInlinePolicy(livenessPolicy); // allows guest user access
backend.auth.resources.authenticatedUserIamRole.attachInlinePolicy(livenessPolicy); // allows logged in user access
```

  </Tabs.Panel>
  <Tabs.Panel value="Amplify CLI">
> Use the Amplify Gen 1 CLI to automatically configure and manage your Cognito Identity and User Pool for you.

FaceLivenessDetector uses Amplify Auth by default to authorize users to perform the Face Liveness check. If you are using Amplify for the first time, follow the instructions for [installing the Amplify CLI](https://docs.amplify.aws/cli/start/install/).

#### Set up a new Amplify project

```bash
$ amplify init
? Enter a name for the project reactliveness
? Enter a name for the environment dev
? Choose your default editor: Visual Studio Code
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path:  src
? Distribution Directory Path: build
? Build Command:  npm run-script build
? Start Command: npm run-script start
```

<CLI />

#### Push to create the resources

```bash
$ amplify push
✔ Successfully pulled backend environment dev from the cloud.

Current Environment: dev

| Category | Resource name    | Operation | Provider plugin   |
| -------- | ---------------- | --------- | ----------------- |
| Auth     | reactlive••••••• | Create    | awscloudformation | 
```

_If you have an existing Amplify backend, run `amplify pull` to sync your `aws-exports.js` with your cloud backend._

Once complete you should now have an `aws-exports.js` file in your `src` directory with your latest Amplify backend configuration.

<Liveness />
  </Tabs.Panel>
    <Tabs.Panel value="Amplify CLI Import">
> If you previously had unmanaged resources that you want to manage with Amplify Gen 1 you can use the CLI to import your Cognito resources.

FaceLivenessDetector uses Amplify Auth by default to authorize users to perform the Face Liveness check. Follow the instructions for [Amplify CLI (Import)](https://docs.amplify.aws/lib/auth/getting-started/q/platform/js/#set-up-backend-resources) to manage your Cognito resources with Amplify.

Once complete you should now have an `aws-exports.js` file in your `src` directory with your latest Amplify backend configuration.

<Liveness />
  </Tabs.Panel>
  <Tabs.Panel value="Self Managed Cognito Resource">
> Use this option if you already have a Cognito identity/user pools that you do not want to import to Amplify, or want to manage Cognito resources yourself or with a 3rd party resource management tool.

If you already have Cognito set up or do not want to use the Amplify Gen 1 CLI to generate Cognito resources, you can follow the documentation in the [existing resources tab](https://docs.amplify.aws/lib/auth/getting-started/q/platform/js/#set-up-backend-resources) or check out the code snippet below.

_If you are manually setting up an identity pool in the Cognito console you can follow [this guide](https://docs.aws.amazon.com/cognito/latest/developerguide/getting-started-with-identity-pools.html#create-identity-pool). When setting up the identity pool ensure that access to unauthenticated identities is enabled._

When initially configuring Amplify you can pass in the cognito region and an identity pool instead of using the Amplify generated aws-exports file.

```jsx
import React from 'react';
import { ThemeProvider } from '@aws-amplify/ui-react';
import { Amplify } from 'aws-amplify';
import '@aws-amplify/ui-react/styles.css';
import awsexports from './aws-exports';

Amplify.configure({
   ...awsexports,
  "aws_cognito_region": "us-east-2", // (required) - Region where Amazon Cognito project was created
  "aws_cognito_identity_pool_id": "us-east-2:xxx-xxx-xxx-xxx-xxx", // (required) - the pool region should match the cognito region
});

export default function App() {
  return (
    <ThemeProvider>
    </ThemeProvider>
  );
}
```

<Liveness />

  </Tabs.Panel>
  <Tabs.Panel value="Custom Credentials Provider">
> Use this option if you want more control over the process of obtaining AWS credentials.

By default, FaceLivenessDetector uses Amplify Auth to authorize users to perform the Face Liveness check. You can use your own credentials provider to retrieve credentials from [Amazon Cognito](https://aws.amazon.com/cognito/) or assume a role with [Amazon STS](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html), for example:

```jsx
import { FaceLivenessDetectorCore, AwsCredentialProvider } from '@aws-amplify/ui-react-liveness';
 
const credentialProvider: AwsCredentialProvider = async () => {
  // Fetch the credentials
}

return (
  <FaceLivenessDetectorCore
    sessionId={'<sessionId>'}
    region={'<region>'}
    onAnalysisComplete={() => {}}
    onError={onError}
    config={{ credentialProvider }}
  />
);
```

  <Callout />

  <Liveness />
  </Tabs.Panel>
</Tabs.Container>

### Step 2. Install dependencies

<InstallScripts component='liveness' />

### Step 3. Initialize Amplify

<AppDirectoryAlert />

```jsx
import React from 'react';
import { ThemeProvider } from '@aws-amplify/ui-react';
import { Amplify } from 'aws-amplify';
import '@aws-amplify/ui-react/styles.css';
import awsexports from './aws-exports';

Amplify.configure(awsexports);

export default function App() {
  return (
    <ThemeProvider>
    </ThemeProvider>
  );
}
```

### Step 4. Add FaceLivenessDetector

To get started you will need to make a request to your backend to receive a `sessionId` and pass that to the `FaceLivenessDetector` component.

Once a valid sessionId, region, and callback has been passed, FaceLivenessDetector will take care of streaming video and presenting Face Liveness challenges.

<Tabs.Container defaultValue="Javascript">
  <Tabs.List>
    <Tabs.Item value="Javascript">Javascript</Tabs.Item>
    <Tabs.Item value="TypeScript">TypeScript</Tabs.Item>
  </Tabs.List>
  <Tabs.Panel value="TypeScript">
```tsx file=./QuickStartReact.tsx
```
  </Tabs.Panel>
  <Tabs.Panel value="Javascript">
```tsx file=./QuickStartReact.jsx
```
  </Tabs.Panel>
</Tabs.Container>

#### Error handling

When errors occur during liveness detection, It is required to create a new session before allowing users to retry. Session IDs are single-use and cannot be reused after an error.
